
import pygame
import random

#全局常量定义
SCREEN_RECT = pygame.rect(0,0,480,700)      #游戏窗口区域
FRAME_INTERVAL = 10                     #逐帧动画间隔帧数

HERO_BOMB_COUNT = 3                     #英雄默认炸弹数
HERO_DEFAULT_MID_BOTTOM = (SCREEN_RECT.centerx,SCREEN_RECT.bottom - 90)

#游戏窗口区域
SCREEN_RECT =pygame.Rect(0,0,480,700)
FRAME_INTERVAL =10              #逐帧动画间隔帧数

class Gamesprite(pygame.sprite.Sprite):
    """游戏精灵类"""
    res_path ="./res/images/"          #图片资源路径
    def __init__(self, image_name, speed, *groups):
        """构造方法
        :param image_name:要加载的图片文件名
        :param speed:移动速度,a表示静止
        :param groups:要添加到的精灵组，不传则不添加
        """
        super().__init__(*groups)
        self.image=pygame.image.load(self.res_path +image_name)
        self.rect = self.image.get_rect()       #矩形区域，默认在左上角
        self.speed = speed          #移动速度

    def update(self,*args):
        """更新精灵位置，默认在垂直方向移动"""
        self.rect.y += self.speed    #改变y值实现1垂直移动

class Background(Gamesprite):
    """背景静静类"""
    def __init__(self, is_alt, *groups):
        #调用父类方法实现
        super().__init__( "background.png" , 1 ,*groups)
        #判断是否是另一精灵
        if is_alt:
            self.rect.y = -self.rect.h

    def update(self, *args):
        #调用父类向下运动
        super().update(*args)


        #判断是否移除游戏窗口
        if self.rect.y >=self.rect.h:
            self.rect.y = -self.rect.h
class statusButton(Gamesprite):
    """状态按钮类"""
    def __init__(self, image_name, *groups):
        """构造方法
        :param image_name:要加载的名称列表
        :param groups: 要添加的精灵族"""

        #调用父类方法实现精灵创建
        super().__init__(image_name[0],0, *groups)
        #加载图像
        self.images =[pygame.image.load(self.res_path +name) for name in image_name]

    def switch_ststus(self,is_pause):
        """切换状态
        :param is_pause: 是否暂停
        """
        self.image = self.images[1 if is_pause else 0]

class Label(pygame.sprite.Sprite):
    """文本标签精ling"""
    font_path ="./res/font/MarkerFelt.ttc"     # 字体文件路径

    def __init__(self, text, size, color, *groups):
        """初始化方法
        :param text: 文本内容
        :param size: 字体大小
        :param color: 字体颜色
        :param groups: 要添加到的精灵组

        """        #调用父类方法实现精灵的创建label
        super().__init__(* groups)

        self.font = pygame.font.Font(self.font_path,size)
        self.color = color
        self.image = self.font.render(text,True,self.color)
        self.rect = self.image.get_rect()

    def set_text(self, text):
        """设置文本,使用指定的文本重新渲染image,并且更新rect
        :param text:文本内容
        """
        self.image = self.font.render(text,True,self.color)
        self.rect = self.image.get_rect()
class Plane(Gamesprite):
    """飞机类"""
    def __init__(self, hp, speed, value, wav_name,normal_names, hurt_name, destroy_names, *groups):
        """初始化方法
        :param hp:生命值
        :param speed:速度
        :param value:得分
        :param wav_name:音频文件名
        :param normal_names:正常飞行图像名称列表
        :param hurt_name:受伤图像文件名
        :param destroy_names:被摧毁图像文件名
        :param groups:要添加到的精灵组

        """
        super().__init__(normal_names[0],speed,*groups)
        #飞机属性
        self.hp = hp
        self.max_hp =hp
        self.value = value
        self.wav_name = wav_name
        #图像属性
        #正常图像列表及索引
        
        self.normal_images = [pygame.image.load(self.res_path + name) for name in normal_names]
        self.normal_index = 0
        #受伤图像
        self.hurt_image = pygame.image.load(self.res_path + hurt_name)

    #被摧毁图像列表及索引
        self.destroy_images = [pygame.image.load(self.res_path + name) for name in destroy_names]
        self.destroy_index = 0
    def update(self, *args):
        #如果地0个参数魏false，不需要更新图像，直接返回
        if not args[0]:
            return
        #设置图像
        self.image = self.normal_images[self.normal_index]
        #更新索引
        count = len(self.normal_images)
        self.normal_index = (self.normal_index +1)% count

    def reset_plane(self):
        """重置飞机"""
        self.hp = self.max_hp           #生命值
        self.normal_index = 0           #正常状态图像索引
        self.destroy_index = 0          #被摧毁状态图像索引
        self.image = self.normal_images[0]  #恢复正常图像
    
    def update(self, *args):
        #如果第o个参数为False，不需要更新图像，直接返回
        if not args[0]:
            return
        #判断飞机状态                           #未受伤
        if self.hp == self.max_hp:
            self.image = self.normal_images[self.normal_index]
            count = len(self.normal_images)
            self.normal_index = (self.normal_index + 1) % count
        elif self.hp > 0:                       #受伤
            self.image = self.hurt_image#被摧毁
        else:
            #判断是否显示到最后一张图像，如果是说明飞机完全被摧毁
            if self.destroy_index < len(self.destroy_images):
                self.image = self.destroy_images[self.destroy_index]
                self.destroy_index += 1
            else:
                self.reset_plane()              #重置飞机super
class Enemy(Plane):
    """敌机类"""
    def __init__(self, kind, max_speed, *groups):
        """敌机类"""
        #记录敌机类型和最大速度
        self.kind = kind
        self.max_speed=max_speed
        #根据类型调用父类方法传递不同参数
        if kind ==0:
           super().__init__(1, 1, 1000, "enemy1_down.wav",["enemy1.png"],"enemy1.png",
                                    ["enemy1_down%d.png" % i for i in range(1, 5)],*groups)
        elif kind == 1:
            super().__init__(6, 1, 6000, "enemy2_down.wav",["enemy2.png"],"enemy2_hit.png",
                ["enemy2_down%d.png" % i for i in range(1, 5)],*groups)
        else:
            super().__init__(15, 1, 15000, "enemy3_down.wav",
                                    ["enemy3_n1.png", "enemy3_n2.png"],"enemy3_hit.png",
                                    ["enemy3_down%d.png" % i for i in range(1, 7)],*groups)
            #3.调用重置飞机方法，设置敌机初始位置和速度
        self.reset_plane()
    def reset_plane(self):
        """重置飞机"""
        super().reset_plane()
        #设置初始随机位置和速度
        x = random.randint(0,SCREEN_RECT.w - self.rect.w)                       #设置随机x位置
        y = random.randint(0,SCREEN_RECT.h - self.rect.h) -SCREEN_RECT.h       #设置随机y位置
        self.rect.topleft =(x,y)                                            #设置初始位置
        self.speed = random.randint(1,self.max_speed)           #设置初始速度
    def update(self, *args):
        """更新图像和位置"""
        #调用父类方法更新飞机图像
        super().update(*args)
        #判断敌机是否被摧毁，更新飞机位置
        if self.hp>0:
            self.rect.y+=self.speed
        #判断是否飞出屏幕，如果是重置飞机
        if self.rect.y>=SCREEN_RECT.h:
            self.reset_plane()

class Hero(Plane):
    """英雄类"""

    def __init__ (self,*groups):
        """初始化方法
        :param groups :要添加的精灵组
        """
        super().__init__(1000,5,0,"me_down.wav",
        ["me%d.png" % i for i in range(1, 3)],
        "me1.png",
        ["me_destroy_%d.png" % i for i in range(1, 5)],
        *groups)
        
        self.is_power = False           #无敌标记
        self.bomb_count = HERO_BOMB_COUNT       #炸弹数量
        self.bullets_kind = 0             #子弹类型
        self.bullets_group = pygame.sprite.Group()      #子弹精灵组
        #初始位置
        self.rect.midbottom =HERO_DEFAULT_MID_BOTTOM
